package com.winhxd.b2c.order.service.impl;

import com.winhxd.b2c.common.cache.Cache;
import com.winhxd.b2c.common.cache.Lock;
import com.winhxd.b2c.common.cache.RedisLock;
import com.winhxd.b2c.common.constant.*;
import com.winhxd.b2c.common.context.CustomerUser;
import com.winhxd.b2c.common.context.UserContext;
import com.winhxd.b2c.common.domain.ResponseResult;
import com.winhxd.b2c.common.domain.customer.model.CustomerShoppingMallRule;
import com.winhxd.b2c.common.domain.customer.model.CustomerUserInfo;
import com.winhxd.b2c.common.domain.customer.vo.CustomerAddressVO;
import com.winhxd.b2c.common.domain.customer.vo.CustomerUserInfoVO;
import com.winhxd.b2c.common.domain.message.condition.MiniMsgCondition;
import com.winhxd.b2c.common.domain.message.condition.MiniTemplateData;
import com.winhxd.b2c.common.domain.message.enums.MiniMsgTypeEnum;
import com.winhxd.b2c.common.domain.order.condition.*;
import com.winhxd.b2c.common.domain.order.enums.*;
import com.winhxd.b2c.common.domain.order.model.*;
import com.winhxd.b2c.common.domain.order.vo.*;
import com.winhxd.b2c.common.domain.product.condition.ProductSkuListCondition;
import com.winhxd.b2c.common.domain.product.condition.ProductStockSkuCondition;
import com.winhxd.b2c.common.domain.product.vo.ProductShopcarSkuVO;
import com.winhxd.b2c.common.exception.BusinessException;
import com.winhxd.b2c.common.feign.customer.CustomerServiceClient;
import com.winhxd.b2c.common.feign.product.ProductServiceClient;
import com.winhxd.b2c.common.mq.MQDestination;
import com.winhxd.b2c.common.mq.StringMessageSender;
import com.winhxd.b2c.common.mq.event.EventMessageSender;
import com.winhxd.b2c.common.mq.event.EventType;
import com.winhxd.b2c.common.util.DateUtil;
import com.winhxd.b2c.common.util.JsonUtil;
import com.winhxd.b2c.common.util.MessageSendUtils;
import com.winhxd.b2c.order.OrderServiceApplication;
import com.winhxd.b2c.order.dao.*;
import com.winhxd.b2c.order.service.OrderAfterSaleDetailService;
import com.winhxd.b2c.order.service.OrderService;
import com.winhxd.b2c.order.util.OrderUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hjw
 * @create 2019-01-08 18:29
 **/
@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    private static final int MAX_ORDER_POSTFIX = 999999999;

    private static final int ORDER_MONEY_SCALE = 2;

    private static final int ORDER_UPDATE_LOCK_EXPIRES_TIME = 5000;

    private static final int ORDER_CREATE_LOCK_EXPIRES_TIME = 3000;

    private static final int USER_FIRST_LEVEL = 1;

    private static final int USER_TWO_LEVEL= 2;

    private static final int USER_MEMBER_LEVEL = 0;

    @Autowired
    OrderInfoMapper orderInfoMapper;

    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Autowired
    OrderLogMapper orderLogMapper;
    @Autowired
    OrderProductInfoMapper orderProductInfoMapper;
    @Autowired
    OrderProductAttributeMapper orderProductAttributeMapper;

    @Autowired
    OrderShoppingLinkMapper orderShoppingLinkMapper;

    @Autowired
    OrderConsigneeMessageMapper orderConsigneeMessageMapper;

    @Autowired
    OrderMemberMessageMapper orderMemberMessageMapper;

    @Autowired
    OrderCancelInfoMapper orderCancelInfoMapper;

    @Autowired
    OrderRebateRecordMapper orderRebateRecordMapper;

    @Autowired
    OrderShoppingCartMapper shoppingCartMapper;

    @Autowired
    OrderAfterSaleDetailMapper orderAfterSaleDetailMapper;

    @Autowired
    ProductServiceClient productServiceClient;

    @Autowired
    CustomerServiceClient customerServiceClient;
    @Autowired
    MessageSendUtils messageSendUtils;
    @Autowired
    private OrderAfterSaleDetailService afterSaleDetailService;
    @Autowired
    private Cache cache;

    @Autowired
    private StringMessageSender stringMessageSender;

    @Autowired
    private EventMessageSender eventMessageSender;

    @Autowired
    private MessageSendUtils messageServiceClient;

    @Autowired
    private  OrderAfterSaleDetailService orderAfterSaleDetailService;


    private static final String KEYWORD1 = "keyword1";
    private static final String KEYWORD2 = "keyword2";
    private static final String KEYWORD3 = "keyword3";
    private static final String KEYWORD4 = "keyword4";
    private static final String KEYWORD5 = "keyword5";



    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderInfo createOrder(CustomerUser customer,OrderCreateCondition orderCreateCondition) {
        String lockKey = CacheName.CACHE_KEY_CUSTOMER_ORDER_REPEAT + orderCreateCondition.getCustomerId();
        Lock lock = new RedisLock(cache, lockKey, ORDER_CREATE_LOCK_EXPIRES_TIME);
        try {
            if(lock.tryLock()){

                validateOrderCreateCondition(orderCreateCondition);
                logger.info("创建订单开始：orderCreateCondition={}", orderCreateCondition);
                //缓存获取订单自动关闭时间
                CustomerShoppingMallRule customerShoppingMallRule = JsonUtil.parseJSONObject(cache.get(CacheName.SHOPPING_MALL_RULE), CustomerShoppingMallRule.class);
                if(customerShoppingMallRule==null || null == customerShoppingMallRule.getOrderReceiveRule()){
                    logger.error("缓存读取自动收货时间为空");
                    throw new BusinessException(BusinessCode.CODE_406204);
                }
                // 生成订单主体信息
                OrderInfoVO orderInfoVO = assembleOrderInfo(orderCreateCondition);
                //获取预计收益
                OrderRebateRecordSaveVO orderRebateRecordSaveVO = getOrderRebateRecord(orderInfoVO,orderCreateCondition);
                //保存订单信息
                OrderInfo orderInfo = saveOrderInfo(orderInfoVO,orderRebateRecordSaveVO,customerShoppingMallRule);
                //订单详情、商品保存
                saveOrderDetail(orderInfoVO.getOrderDetailVOList());
                //订单收货人信息
                saveConsigneeMessage(orderCreateCondition, orderInfo);
                //保存订单会员信息
                saveMemberMessage(orderInfo);
                //保存预计收益
                saveOrderRebateRecord(orderRebateRecordSaveVO.getOrderRebateRecordList());
                //订单购物车转换关系
                saveOrderShoppingLink(orderInfoVO,orderCreateCondition);
                // 生成订单日志
                saveOrderLog(orderInfo, OrderOperationPropertyEnum.CREATED.getPropertyDes());
                //订单创建后相关业务操作
                logger.info("创建订单结束orderNo：{}", orderInfoVO.getOrderNo());
                //修改商品库存
                orderOperateProductStock(orderInfoVO.getOrderDetailVOList(),orderInfo,1);
                //发送延时消息取消订单
                stringMessageSender.send(MQDestination.OUTLET_ORDER_PAY_TIMEOUT_DELAYED, orderInfo.getOrderNo(), customerShoppingMallRule.getOrderCloseRule()*60*1000);
                try {
                    //发送模板消息
                    String orderTotal ="￥"+ orderInfo.getOtherTotal().toString();
                    String openid = customer.getOpenid();
                    String page = null;
                    MiniTemplateData data1 = new MiniTemplateData();
                    data1.setKeyName(KEYWORD1);
                    data1.setValue(orderInfo.getOrderNo());
                    MiniTemplateData data2 = new MiniTemplateData();
                    data2.setKeyName(KEYWORD2);
                    data2.setValue(orderTotal);
                    MiniTemplateData data3 = new MiniTemplateData();
                    data3.setKeyName(KEYWORD3);
                    data3.setValue(OrderStatusEnum.getDesByCode(orderInfo.getStatus()));
                    MiniTemplateData data4 = new MiniTemplateData();
                    data4.setKeyName(KEYWORD4);
                    String orderDate= DateUtil.dateToString(orderInfo.getCreated(),"yyyy年MM月dd HH:mm:ss");
                    data4.setValue(orderDate);
                    MiniTemplateData data5 = new MiniTemplateData();
                    data5.setKeyName(KEYWORD5);
                    data5.setValue(" 我们会及时为您发货，谢谢惠顾");
                    short msgType2C = MiniMsgTypeEnum.ORDER_CREATED.getMsgType();
                    MiniMsgCondition miniMsgCondition = OrderUtils.genMiniMsgCondition(openid, page, msgType2C, null, data1, data2, data3, data4, data5);
                    messageServiceClient.sendMiniTemplateMsg(miniMsgCondition);
                } catch (Exception e) {
                    logger.error("创建订单给用户发送消息失败：", e);
                }
                return orderInfo;

            }else {
                throw new BusinessException(BusinessCode.CODE_401014);
            }
        }finally {
            lock.unlock();
        }

    }


    @Override
    public int updateByOrderNo(OrderInfo record) {
        return orderInfoMapper.updateByOrderNo(record);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderRevokeAfterSale(OrderStartAfterSaleCondition condition) {
        OrderDetail oDetail = getOrderDetail(condition, AfterSaleTypeEnum.NORMAL.getTypeCode());
        int uOrder = orderDetailMapper.updateByOrderNoAndSkuId(oDetail);
        if (uOrder != 1) {
            logger.error("=--更新订单{}商品{}状态失败", condition.getOrderNo(), condition.getSkuId());
            throw new BusinessException(BusinessCode.ORDER_STATUS_CHANGE_FAILURE);
        }
        // TODO: 2019/1/9  更新售后订单
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startAfterSale(OrderStartAfterSaleCondition condition) {
        OrderDetail oDetail = getOrderDetail(condition, condition.getAfterSaleType());
        int uOrder = orderDetailMapper.updateByOrderNoAndSkuId(oDetail);
        // TODO: 2019/1/9

    }

    private OrderDetail getOrderDetail(OrderStartAfterSaleCondition condition, int afterSaleType) {
        CustomerUser customer = UserContext.getCurrentCustomerUser();
        //修改订单状态
        OrderDetail oDetail = new OrderDetail();
        oDetail.setOrderNo(condition.getOrderNo());
        oDetail.setSkuId(condition.getSkuId());
        oDetail.setUpdated(new Date());
        oDetail.setUpdatedBy(String.valueOf(customer.getCustomerId()));
        oDetail.setFlowStatus(afterSaleType);
        return oDetail;
    }

    /**
     * @param orderNo
     * @return
     * @author hjw
     * @date 2019/1/9 16:54
     * @Description 根据订单编码查询订单信息
     */
    @Override
    public OrderInfo selectByOrderNo(String orderNo) {
        return orderInfoMapper.selectByOrderNo(orderNo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrderByCustomer(CustomerUser customer, OrderCancelCondition condition) {
        String orderNo = condition.getOrderNo();

        if (StringUtils.isBlank(orderNo)) {
            throw new BusinessException(BusinessCode.ORDER_NO_EMPTY);
        }
        String lockKey = CacheName.CACHE_KEY_MODIFY_ORDER + orderNo;
        Lock lock = new RedisLock(cache, lockKey, ORDER_UPDATE_LOCK_EXPIRES_TIME);
        try {
            lock.lock();
            OrderInfo orderInfo = orderInfoMapper.selectByOrderNo(orderNo);
            if (!orderInfo.getCustomerId().equals(customer.getCustomerId())) {
                throw new BusinessException(BusinessCode.ORDER_INFO_NOT_MATCH_ERROR,
                        MessageFormat.format("该订单不是登录用户的订单orderNo={0},orderCustomerId={1},customerId={2}", orderInfo.getOrderNo(), orderInfo.getCustomerId(), customer.getCustomerId()));
            }
            if (orderInfo == null) {
                logger.info("订单号：{}未找到对应订单，无法执行订单未支付超时处理", orderNo);
                return;
            }
            if (orderInfo.getStatus() != OrderStatusEnum.WAIT_PAY.getStatusCode()) {
                logger.info("订单：{} 状态：{} 非待付款状态，无需进行超时取消操作", orderNo,
                        orderInfo.getStatus());
                return;
            }
            //取消
            orderCancel(orderInfo, condition.getCancelReason(),OrderStatusEnum.CANCELED.getStatusCode(),
                    OrderExtendStatusEnum.MANUAL_CENCEL.getStatusCode(), condition.getCancelType(), condition.getCancelCode(),OrderOperationPropertyEnum.CENCEL.getPropertyDes());
        }finally {
            lock.unlock();
        }
    }

    @Override

    public List<OrderRebateRecordVO> orderCalculateRevenue(OrderInfo orderInfo, Boolean type) {
        //查询订单明细
        List<OrderDetailVO> orderDetailVOS = orderDetailMapper.selectListByOrderNoAndStatus(orderInfo.getOrderNo(), OrderDetailStatusEnum.EFFECTIVE.getStatusCode());
        List<OrderRebateRecord> orderRebateRecordList = orderRebateRecordCalculate(orderInfo, orderDetailVOS, type);
        // TODO 调取修改接口

        List<OrderRebateRecordVO> orderRebateRecordVOList = new ArrayList<>();
        orderRebateRecordList.stream().forEach(orderRebateRecord -> {
            OrderRebateRecordVO orderRebateRecordVO = new OrderRebateRecordVO();
            BeanUtils.copyProperties(orderRebateRecord, orderRebateRecordVO);
            orderRebateRecordVOList.add(orderRebateRecordVO);
        });
        return orderRebateRecordVOList;
    }

    @Override
    public List<OrderRebateRecord> orderRebateRecordCalculate(OrderInfo orderInfo, List<OrderDetailVO> orderDetailVOS, Boolean type) {
        String logSign = "#收益计算# - ";
        logger.info(logSign + "计算开始 orderNo=" + orderInfo.getOrderNo() + "type=" + type);
        List<OrderRebateRecord> orderRebateRecordList = new ArrayList<>();
        if (type){
            List<Long> skuIds = orderDetailVOS.stream().map(orderDetailVO -> orderDetailVO.getSkuId()).collect(Collectors.toList());
            //查询商品相关信息
            Map<Long, ProductShopcarSkuVO> skuInfoMap = querySkuInfos(orderInfo.getCustomerId(), skuIds);
            logger.info(logSign + "用户渠道信息 orderNo=" + orderInfo.getOrderNo() + "type=" + type + "info=" + JsonUtil.toJSONString(skuInfoMap));
            //计算订单收益
            if (skuInfoMap != null && skuInfoMap.size() > 0) {
                orderDetailVOS.stream().forEach(orderDetailVO -> {
                    ProductShopcarSkuVO cartProdVO = skuInfoMap.get(orderDetailVO.getSkuId());
                    OrderRebateRecord orderRebateRecord = new OrderRebateRecord();
                    if (cartProdVO != null) {
                        BigDecimal price = cartProdVO.getSalePrice();
                        if (price != null) {
                            orderRebateRecord.setOrderNo(orderInfo.getOrderNo());
                            orderRebateRecord.setSkuId(Long.valueOf(cartProdVO.getSkuId()==null?0:cartProdVO.getSkuId()));
                            orderRebateRecord.setVipId(orderInfo.getCustomerId());
                            orderRebateRecord.setFirstAgentId(orderInfo.getFirstAgent());
                            orderRebateRecord.setTwoAgentId(orderInfo.getTwoAgent());

                            //一级
                            BigDecimal firstProfit = price.multiply(new BigDecimal(orderDetailVO.getNumber())).multiply(cartProdVO.getFirstIncome())
                                    .setScale(ORDER_MONEY_SCALE, RoundingMode.HALF_UP);
                            Integer firstPonint = price.multiply(new BigDecimal(orderDetailVO.getNumber())).multiply(BigDecimal.valueOf(cartProdVO.getFirstPoint())).intValue();
                            //二级
                            BigDecimal twoProfit = price.multiply(new BigDecimal(orderDetailVO.getNumber())).multiply(cartProdVO.getSecondIncome())
                                    .setScale(ORDER_MONEY_SCALE, RoundingMode.HALF_UP);
                            Integer twoPonint = price.multiply(new BigDecimal(orderDetailVO.getNumber())).multiply(BigDecimal.valueOf(cartProdVO.getSecondPoint())).intValue();
                            //会员
                            BigDecimal memberProfit = price.multiply(new BigDecimal(orderDetailVO.getNumber())).multiply(cartProdVO.getMemberIncome())
                                    .setScale(ORDER_MONEY_SCALE, RoundingMode.HALF_UP);
                            Integer memberPonint = price.multiply(new BigDecimal(orderDetailVO.getNumber())).multiply(BigDecimal.valueOf(cartProdVO.getMemberPoint())).intValue();

                            orderRebateRecord.setStatus(OrderRebateStatusEnum.WAIT_CORRECTION.getStatusCode());
                            orderRebateRecord.setFirstAgentEstimateProfit(firstProfit);
                            orderRebateRecord.setFirstAgentEstimateIntegral(firstPonint);
                            orderRebateRecord.setVipEstimateProfit(memberProfit);
                            orderRebateRecord.setVipEstimateIntegral(memberPonint);
                            //会员直接在一级分销商下单，二级奖励赋予一级分销商
                            if (Objects.isNull(orderInfo.getTwoAgent())){
                                orderRebateRecord.setFirstAgentEstimateProfit(firstProfit.add(twoProfit));
                                orderRebateRecord.setFirstAgentEstimateIntegral(firstPonint + twoPonint);
                            }else {
                                orderRebateRecord.setTwoAgentEstimateIntegral(twoPonint);
                                orderRebateRecord.setTwoAgentEstimateProfit(twoProfit);
                            }
                            orderRebateRecordList.add(orderRebateRecord);
                        }
                    }
                });
            }
        }else {
            //查询有效的订单奖励信息
//            orderRebateRecordMapper.selectListByOrderNoAndStatus(orderInfo.getOrderNo(), );
        }
        logger.info(logSign + "计算完成 orderNo=" + orderInfo.getOrderNo() + "type=" + type + "list=" + JsonUtil.toJSONString(orderRebateRecordList));
        return orderRebateRecordList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderReadVO readyOrder(CustomerUser customer, OrderReadyCondition condition) {
        OrderReadVO orderReadVO = new OrderReadVO();

        ResponseResult<CustomerAddressVO> ret = customerServiceClient.selectDefaultCustomerAddress(customer.getCustomerId());
        List<CustomerAddressVO> customerAddressVOList = new ArrayList<>();
        if(null != ret.getData()){
            customerAddressVOList.add(ret.getData());
        }
        orderReadVO.setCustomerAddressVOList(customerAddressVOList);
        return orderReadVO;
    }

    /**
     * 保存订单会员信息
     *
     * @param orderInfo
     * @author wangxiaoshun
     */
    private void saveMemberMessage(OrderInfo orderInfo) {
        ResponseResult<CustomerUserInfoVO> ret = customerServiceClient.getCustomerUserInfoById(orderInfo.getCustomerId());
        if (null == ret.getData()) {
            logger.error("订单：{}用户：customerId={}, 返回结果:code={} 用户不存在，创建订单异常！~", orderInfo.getOrderNo(),
                    orderInfo.getCustomerId(), ret == null ? null : ret.getCode());
            throw new BusinessException(BusinessCode.CODE_401009);
        }

        OrderMemberMessage orderMemberMessage = new OrderMemberMessage();
        orderMemberMessage.setCustomerId(ret.getData().getId());
        orderMemberMessage.setName(ret.getData().getNickName());
        orderMemberMessage.setMobile(ret.getData().getCustomerMobile());
        orderMemberMessage.setOrderNo(orderInfo.getOrderNo());
        orderMemberMessage.setDistributionLevel(String.valueOf(ret.getData().getLevel()));
        orderMemberMessage.setCreatedBy(orderInfo.getCustomerId());
        orderMemberMessage.setCreated(orderInfo.getCreated());
        orderMemberMessageMapper.insertSelective(orderMemberMessage);
    }

    /**
     * 保存收货人信息
     *
     * @param orderCreateCondition
     * @param orderInfo
     * @author wangxiaoshun
     */
    private void saveConsigneeMessage(OrderCreateCondition orderCreateCondition, OrderInfo orderInfo) {
        ResponseResult<CustomerAddressVO> ret = customerServiceClient.selectCustomerAddressById(orderCreateCondition.getAddressId());
        if (null == ret.getData()) {
            logger.error("订单：{}地址：addressId={}, 返回结果:code={} 地址不存在，创建订单异常！~", orderInfo.getOrderNo(),
                    orderCreateCondition.getAddressId(), ret == null ? null : ret.getCode());
            throw new BusinessException(BusinessCode.CODE_401010);
        }
        //保存收货人地址信息
        OrderConsigneeMessage consigneeMessage = new OrderConsigneeMessage();
        String address =ret.getData().getContacterProvince()+ ret.getData().getContacterCity()+ret.getData().getContacterCounty()+ret.getData().getContacterDetailAddress();
        consigneeMessage.setAddress(address);
        consigneeMessage.setName(ret.getData().getContacterName());
        consigneeMessage.setMobile(ret.getData().getContacterMobile());
        consigneeMessage.setCustomerId(orderInfo.getCustomerId());
        consigneeMessage.setOrderNo(orderInfo.getOrderNo());
        consigneeMessage.setCreated(orderInfo.getCreated());
        consigneeMessage.setStatus(CommonStatusEnum.YES.getTypeCode());
        consigneeMessage.setType(OrderAddressTypeEnmu.RECEIVING.getStatusCode());
        orderConsigneeMessageMapper.insertSelective(consigneeMessage);

        //保存发货人地址信息
        //缓存获取退换地址信息
        CustomerShoppingMallRule customerShoppingMallRule = JsonUtil.parseJSONObject(cache.get(CacheName.SHOPPING_MALL_RULE), CustomerShoppingMallRule.class);
        OrderConsigneeMessage deliverConsigneeMessage = new OrderConsigneeMessage();
        deliverConsigneeMessage.setAddress(customerShoppingMallRule.getSendBackAddress());
        deliverConsigneeMessage.setName(customerShoppingMallRule.getSendBackPerson());
        deliverConsigneeMessage.setMobile(customerShoppingMallRule.getSendBackMobile());
        deliverConsigneeMessage.setCustomerId(orderInfo.getCustomerId());
        deliverConsigneeMessage.setOrderNo(orderInfo.getOrderNo());
        deliverConsigneeMessage.setCreated(orderInfo.getCreated());
        deliverConsigneeMessage.setStatus(CommonStatusEnum.YES.getTypeCode());
        deliverConsigneeMessage.setType(OrderAddressTypeEnmu.DELIVER.getStatusCode());
        orderConsigneeMessageMapper.insertSelective(deliverConsigneeMessage);
    }

    private OrderInfo saveOrderInfo(OrderInfoVO orderInfoVO,OrderRebateRecordSaveVO rebateRecordVO,CustomerShoppingMallRule customerShoppingMallRule){
        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(orderInfoVO, orderInfo);
        orderInfo.setAutoCloseMinute(Long.valueOf(customerShoppingMallRule.getOrderCloseRule()==null?0:customerShoppingMallRule.getOrderCloseRule()));
        orderInfo.setAutoExchangeDay(Long.valueOf(customerShoppingMallRule.getExchangeTime()==null?0:customerShoppingMallRule.getExchangeTime()));
        orderInfo.setFirstAgent(rebateRecordVO.getFirstId());
        orderInfo.setTwoAgent(rebateRecordVO.getTwoId());
        orderInfo.setEstimateIntegral(Long.valueOf(rebateRecordVO.getIntegral()==null?0:rebateRecordVO.getIntegral()));
        orderInfo.setActualIntegral(Long.valueOf(rebateRecordVO.getIntegral()==null?0:rebateRecordVO.getIntegral()));
        orderInfo.setEstimateProfit(rebateRecordVO.getProfit());
        orderInfo.setActualProfit(rebateRecordVO.getProfit());
        orderInfoMapper.insertSelective(orderInfo);
        return orderInfo;
    }
    /**
     * 订单详情、商品保存
     *
     * @param infoDetailVOList
     * @author wangxiaoshun
     */
    private void saveOrderDetail(List<OrderDetailVO> infoDetailVOList) {
        if (CollectionUtils.isEmpty(infoDetailVOList)) {
            return;
        }
        for (OrderDetailVO orderDetailVO : infoDetailVOList) {
            //保存订单详情
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(orderDetailVO, orderDetail);
            orderDetailMapper.insertSelective(orderDetail);

            if (null != orderDetailVO.getOrderProductInfoVO()) {
                //保存订单商品信息
                OrderProductInfoVO orderProductInfoVO = orderDetailVO.getOrderProductInfoVO();
//                OrderProductInfo orderProductInfo = new OrderProductInfo();
//                BeanUtils.copyProperties(orderProductInfoVO, orderProductInfo);
                orderProductInfoVO.setOrderDetailId(orderDetail.getId());
                orderProductInfoMapper.insertSelective(orderProductInfoVO);
                //保存商品属性信息
                if (CollectionUtils.isNotEmpty(orderProductInfoVO.getOrderProductAttributeList())) {
                    for (OrderProductAttribute productAttribute : orderProductInfoVO.getOrderProductAttributeList()) {
                        productAttribute.setOrderProdectInfoId(orderProductInfoVO.getId());
                        orderProductAttributeMapper.insertSelective(productAttribute);
                    }
                }
            }
        }
    }

    /**
     * 组装订单信息
     *
     * @param orderCreateCondition
     * @return
     * @author wangxiaoshun
     */
    private OrderInfoVO assembleOrderInfo(OrderCreateCondition orderCreateCondition) {


        //下单门店信息
        ResponseResult<CustomerUserInfo> ret = customerServiceClient.getParentCustomerUserByCustoemrId(orderCreateCondition.getCustomerId());
        if (null == ret.getData()) {
            logger.error("saveOrderRebateRecord-》订单创建 查询门店信息：{}用户：customerId={}, 返回结果:code={} 用户不存在，创建订单异常！~",
                    orderCreateCondition.getCustomerId(), ret == null ? null : ret.getCode());
            throw new BusinessException(BusinessCode.CODE_401009);
        }

        OrderInfoVO orderInfoVO = new OrderInfoVO();
        orderInfoVO.setCreated(new Date());
        orderInfoVO.setCreatedBy(String.valueOf(orderCreateCondition.getCustomerId()));
        orderInfoVO.setUpdated(new Date());
        orderInfoVO.setUpdatedBy(String.valueOf(orderCreateCondition.getCustomerId()));
        orderInfoVO.setCustomerId(orderCreateCondition.getCustomerId());
        orderInfoVO.setPayStatus(PayStatusEnum.UNPAID.getStatusCode());
        orderInfoVO.setPayType(orderCreateCondition.getPayType());
        orderInfoVO.setOrderNo(generateOrderNo());
        orderInfoVO.setRemarks(orderCreateCondition.getRemark());
        orderInfoVO.setStatus(OrderStatusEnum.WAIT_PAY.getStatusCode());
        orderInfoVO.setStoreName(ret.getData().getStoreName());
        orderInfoVO.setStoreId(ret.getData().getId());
        //组装订单商品信息
        BigDecimal orderTotal = aseembleAndCalculateOrderItems(orderCreateCondition, orderInfoVO);
        orderInfoVO.setTotalMoney(orderTotal);
        orderInfoVO.setOtherTotal(orderTotal);
        return orderInfoVO;
    }

    /**
     * 组装订单商品项明细
     *
     * @param orderCreateCondition
     * @param orderInfoVO
     * @author wangxiaoshun
     * @author wangxiaoshun
     */
    private BigDecimal aseembleAndCalculateOrderItems(OrderCreateCondition orderCreateCondition, OrderInfoVO orderInfoVO) {
        BigDecimal orderTotal = BigDecimal.ZERO;
        List<OrderDetailVO> orderDetails = new ArrayList<>();
        List<Long> skuIds = new ArrayList<>();
        for (Iterator<OrderProductItemCondition> iterator = orderCreateCondition.getProductItemConditions().iterator(); iterator.hasNext(); ) {
            OrderProductItemCondition condition = iterator.next();
            OrderDetailVO orderDetail = new OrderDetailVO();
            BeanUtils.copyProperties(condition, orderDetail);
            orderDetail.setOrderNo(orderInfoVO.getOrderNo());
            orderDetail.setCreated(orderInfoVO.getCreated());
            orderDetail.setCreatedBy(orderInfoVO.getCreatedBy());
            orderDetail.setCreatedBy(orderInfoVO.getCreatedBy());
            orderDetail.setFlowStatus(OrderFlowStatusEnum.NORMAL.getStatusCode());
            orderDetail.setStatus(OrderDetailStatusEnum.EFFECTIVE.getStatusCode());
            skuIds.add(orderDetail.getSkuId());
            orderDetails.add(orderDetail);
        }
        if (orderDetails.isEmpty()) {
            throw new BusinessException(BusinessCode.CODE_401005);
        }
        //查询商品相关信息
        Map<Long, ProductShopcarSkuVO> skuInfoMap = querySkuInfos(orderInfoVO.getCustomerId(), skuIds);
        if (skuInfoMap != null && skuInfoMap.size() > 0) {
            for (Iterator<OrderDetailVO> iterator = orderDetails.iterator(); iterator.hasNext(); ) {
                OrderDetailVO orderDetail = iterator.next();
                OrderProductInfoVO orderProductInfoVO = new OrderProductInfoVO();
                List<OrderProductAttribute> orderProductAttributes = new ArrayList<>();
                ProductShopcarSkuVO skuVO = skuInfoMap.get(orderDetail.getSkuId());
                if (skuVO != null) {
                    if(skuVO.getSaleStatus() == 0 ){
                        throw new BusinessException(BusinessCode.CODE_401015);
                    }
                    if(skuVO.getStockStatus() == 0 || skuVO.getStock() < orderDetail.getNumber()){
                        throw new BusinessException(BusinessCode.CODE_401011);
                    }
                    orderDetail.setMarketPrice(skuVO.getGuidePrice());
                    orderDetail.setSpuId(skuVO.getSpuId());
                    orderDetail.setSpuName(skuVO.getSpuName());
                    orderDetail.setSpuCode(skuVO.getSpuCode());
                    orderDetail.setConversionPrice(skuVO.getSalePrice());
                    orderDetail.setOtherTotal(skuVO.getSalePrice());
                    orderDetail.setSkuUrl(skuVO.getImageUrl());
                    orderDetail.setSkuCode(skuVO.getSkuCode());
                    if(null!=skuVO.getBrandId()){
                        orderDetail.setBrandId(Long.valueOf(skuVO.getBrandId()));
                    }
                    orderDetail.setBrandName(skuVO.getBrandName());
                    orderProductInfoVO.setCreated(orderDetail.getCreated());
                    orderProductInfoVO.setCreatedBy(orderDetail.getCreatedBy());
                    orderProductInfoVO.setSkuId(orderDetail.getSkuId());
                    orderProductInfoVO.setOrderNo(orderDetail.getOrderNo());

                    //组装商品属性
                    if (StringUtils.isNotEmpty(skuVO.getColorName())) {
                        OrderProductAttribute orderProductAttribute = new OrderProductAttribute();
                        orderProductAttribute.setCreated(orderDetail.getCreated());
                        orderProductAttribute.setCreatedBy(orderDetail.getCreatedBy());
                        orderProductAttribute.setProductAttribute("颜色");
                        orderProductAttribute.setProductAttributeValue(skuVO.getColorName());
                        orderProductAttributes.add(orderProductAttribute);
                    }
                    if (StringUtils.isNotEmpty(skuVO.getSizeName())) {
                        OrderProductAttribute orderProductAttribute = new OrderProductAttribute();
                        orderProductAttribute.setCreated(orderDetail.getCreated());
                        orderProductAttribute.setCreatedBy(orderDetail.getCreatedBy());
                        orderProductAttribute.setProductAttribute("尺码");
                        orderProductAttribute.setProductAttributeValue(skuVO.getSizeName());
                        orderProductAttributes.add(orderProductAttribute);
                    }
                    orderProductInfoVO.setOrderProductAttributeList(orderProductAttributes);
                    orderDetail.setOrderProductInfoVO(orderProductInfoVO);
                }
            }
        }else {
            throw new BusinessException(BusinessCode.CODE_401005);
        }
        orderInfoVO.setOrderDetailVOList(orderDetails);

        //计算商品价格信息
        if (skuInfoMap != null && skuInfoMap.size() > 0) {
            for (Iterator<OrderDetailVO> iterator = orderDetails.iterator(); iterator.hasNext(); ) {
                OrderDetailVO orderItem = iterator.next();
                ProductShopcarSkuVO cartProdVO = skuInfoMap.get(orderItem.getSkuId());
                if (cartProdVO != null) {
                    if(cartProdVO.getStockStatus() == 0 || cartProdVO.getStock() < orderItem.getNumber()){
                        throw new BusinessException(BusinessCode.CODE_401011);
                    }
                    BigDecimal price = cartProdVO.getSalePrice();
                    if (price == null) {
                        return null;
                    }
                    orderTotal = orderTotal.add(price.multiply(new BigDecimal(orderItem.getNumber()))
                            .setScale(ORDER_MONEY_SCALE, RoundingMode.HALF_UP));
                } else {
                    throw new BusinessException(BusinessCode.CODE_401005);
                }
            }
        } else {
            throw new BusinessException(BusinessCode.CODE_401005);
        }
        return orderTotal;
    }


    /**
     *
     * @param createCondition
     * @return
     */
    private OrderRebateRecordSaveVO getOrderRebateRecord(OrderInfoVO orderInfoVO, OrderCreateCondition createCondition){
        OrderRebateRecordSaveVO orderRebateRecordSaveVO = new OrderRebateRecordSaveVO();
        List<OrderRebateRecord> orderRebateRecordList = new ArrayList<>();

        List<Long> skuIds = new ArrayList<>();
        //一级分销商id
        Long firstId = null;
        //二级分销商id
        Long twoId = null;
        //订单预计、实际总收益
        BigDecimal profit = new BigDecimal(0);
        //订单预计、实际总积分
        Integer integral = 0;
        //会员上级分销商级别
        Integer parentLevel = USER_TWO_LEVEL;
        //获取二级分销商和一级分销商信息
        ResponseResult<CustomerUserInfoVO> ret = customerServiceClient.getCustomerUserInfoById(orderInfoVO.getCustomerId());
        if (null == ret.getData()) {
            logger.error("saveOrderRebateRecord-》订单创建：{}用户：customerId={}, 返回结果:code={} 用户不存在，创建订单异常！~",
                    orderInfoVO.getCustomerId(), ret == null ? null : ret.getCode());
            throw new BusinessException(BusinessCode.CODE_401009);
        }

        if(ret.getData().getLevel()==USER_FIRST_LEVEL){
            firstId = ret.getData().getId();
        }else if(ret.getData().getLevel()==USER_TWO_LEVEL){
            //二级分销商下单查询一级分销商
            firstId = ret.getData().getParentId();
            twoId = ret.getData().getId();
        }else if(ret.getData().getLevel()==USER_MEMBER_LEVEL){
            //会员下单查询一二级分销商
            ResponseResult<CustomerUserInfoVO> result = customerServiceClient.getCustomerUserInfoById(ret.getData().getParentId());
            if(null!=result.getData()){
                //如果会员上级为一级分销商，二级则为空
                if(result.getData().getLevel()==USER_FIRST_LEVEL){
                    firstId = result.getData().getId();
                    parentLevel = USER_FIRST_LEVEL;
                }else {
                    firstId = result.getData().getParentId();
                    twoId = result.getData().getId();
                }
            }
        }

        for (Iterator<OrderProductItemCondition> iterator = createCondition.getProductItemConditions().iterator(); iterator.hasNext(); ) {
            OrderProductItemCondition condition = iterator.next();
            skuIds.add(condition.getSkuId());
        }

        //查询商品相关信息
        Map<Long, ProductShopcarSkuVO> skuInfoMap = querySkuInfos(orderInfoVO.getCustomerId(), skuIds);
        //计算预算收益
        if (skuInfoMap != null && skuInfoMap.size() > 0) {
            for (OrderDetailVO  orderItem :  orderInfoVO.getOrderDetailVOList()) {
                OrderRebateRecord orderRebateRecord = new OrderRebateRecord();
                ProductShopcarSkuVO cartProdVO = skuInfoMap.get(orderItem.getSkuId());
                if (cartProdVO != null) {
                    if(cartProdVO.getStockStatus() == 0 || cartProdVO.getStock() < orderItem.getNumber()){
                        throw new BusinessException(BusinessCode.CODE_401011);
                    }
                    BigDecimal price = cartProdVO.getSalePrice();
                    if (price != null) {
                        orderRebateRecord.setOrderNo(orderInfoVO.getOrderNo());
                        orderRebateRecord.setSkuId(orderItem.getSkuId());
                        orderRebateRecord.setVipId(orderInfoVO.getCustomerId());
                        orderRebateRecord.setFirstAgentId(firstId);
                        orderRebateRecord.setTwoAgentId(twoId);
                        orderRebateRecord.setCreated(new Date());
                        orderRebateRecord.setStatus(OrderRebateStatusEnum.WAIT_CORRECTION.getStatusCode());
                        //一级
                        BigDecimal firstProfit = cartProdVO.getFirstIncome().multiply(new BigDecimal(orderItem.getNumber()))
                                .setScale(ORDER_MONEY_SCALE, RoundingMode.HALF_UP);
                        Integer firstPonint = BigDecimal.valueOf(cartProdVO.getFirstPoint()).multiply(new BigDecimal(orderItem.getNumber())).intValue();
                        //二级
                        BigDecimal twoProfit = cartProdVO.getSecondIncome().multiply(new BigDecimal(orderItem.getNumber()))
                                .setScale(ORDER_MONEY_SCALE, RoundingMode.HALF_UP);
                        Integer twoPonint = BigDecimal.valueOf(cartProdVO.getSecondPoint()).multiply(new BigDecimal(orderItem.getNumber())).intValue();
                        //会员
                        BigDecimal memberProfit = cartProdVO.getMemberIncome().multiply(new BigDecimal(orderItem.getNumber()))
                                .setScale(ORDER_MONEY_SCALE, RoundingMode.HALF_UP);
                        Integer memberPonint = BigDecimal.valueOf(cartProdVO.getMemberPoint()).multiply(new BigDecimal(orderItem.getNumber())).intValue();

                        //如果当前用户是一级，一级返利为一级+二级，其余不返
                        if(ret.getData().getLevel()==USER_FIRST_LEVEL){
                            orderRebateRecord.setFirstAgentEstimateProfit(firstProfit.add(twoProfit));
                            orderRebateRecord.setFirstAgentActualProfit(firstProfit.add(twoProfit));
                            orderRebateRecord.setFirstAgentEstimateIntegral(firstPonint+twoPonint);
                            orderRebateRecord.setFirstAgentActualIntegral(firstPonint+twoPonint);
                        }
                        //如果当前用户是二级，一级返利为一级,二级返利为二级
                        if(ret.getData().getLevel()==USER_TWO_LEVEL){
                            orderRebateRecord.setFirstAgentEstimateProfit(firstProfit);
                            orderRebateRecord.setFirstAgentActualProfit(firstProfit);
                            orderRebateRecord.setFirstAgentEstimateIntegral(firstPonint);
                            orderRebateRecord.setFirstAgentActualIntegral(firstPonint);

                            orderRebateRecord.setTwoAgentEstimateProfit(twoProfit);
                            orderRebateRecord.setTwoAgentEstimateIntegral(twoPonint);
                            orderRebateRecord.setTwoAgentActualProfit(twoProfit);
                            orderRebateRecord.setTwoAgentActualIntegral(twoPonint);
                        }
                        //如果当前用户是会员，上级是二级返利不变
                        if(ret.getData().getLevel()==USER_MEMBER_LEVEL && parentLevel == USER_TWO_LEVEL){
                            orderRebateRecord.setFirstAgentEstimateProfit(firstProfit);
                            orderRebateRecord.setFirstAgentActualProfit(firstProfit);
                            orderRebateRecord.setFirstAgentEstimateIntegral(firstPonint);
                            orderRebateRecord.setFirstAgentActualIntegral(firstPonint);

                            orderRebateRecord.setTwoAgentEstimateProfit(twoProfit);
                            orderRebateRecord.setTwoAgentEstimateIntegral(twoPonint);
                            orderRebateRecord.setTwoAgentActualProfit(twoProfit);
                            orderRebateRecord.setTwoAgentActualIntegral(twoPonint);

                            orderRebateRecord.setVipEstimateIntegral(memberPonint);
                            orderRebateRecord.setVipActualIntegral(memberPonint);
                            orderRebateRecord.setVipEstimateProfit(memberProfit);
                            orderRebateRecord.setVipActualProfit(memberProfit);
                        }
                        //上级是一级，一级返利为一级+二级
                        if(ret.getData().getLevel()==USER_MEMBER_LEVEL && parentLevel == USER_FIRST_LEVEL){
                            orderRebateRecord.setFirstAgentEstimateProfit(firstProfit.add(twoProfit));
                            orderRebateRecord.setFirstAgentActualProfit(firstProfit.add(twoProfit));
                            orderRebateRecord.setFirstAgentEstimateIntegral(firstPonint+twoPonint);
                            orderRebateRecord.setFirstAgentActualIntegral(firstPonint+twoPonint);

                            orderRebateRecord.setVipEstimateIntegral(memberPonint);
                            orderRebateRecord.setVipActualIntegral(memberPonint);
                            orderRebateRecord.setVipEstimateProfit(memberProfit);
                            orderRebateRecord.setVipActualProfit(memberProfit);
                        }
                        profit = profit.add(firstProfit).add(twoProfit).add(memberProfit);
                        integral = integral + firstPonint+twoPonint+memberPonint;
                        orderRebateRecordList.add(orderRebateRecord);
                    }
                } else {
                    throw new BusinessException(BusinessCode.CODE_401005);
                }
            }
        }
        orderRebateRecordSaveVO.setFirstId(firstId);
        orderRebateRecordSaveVO.setTwoId(twoId);
        orderRebateRecordSaveVO.setIntegral(integral);
        orderRebateRecordSaveVO.setProfit(profit);
        orderRebateRecordSaveVO.setOrderRebateRecordList(orderRebateRecordList);
        return  orderRebateRecordSaveVO;
    }


    /**
     * wangxiaoshun
     * 保存订单预计收益
     *
     * @param orderRebateRecordList
     */
    private void saveOrderRebateRecord(List<OrderRebateRecord> orderRebateRecordList) {
        for(OrderRebateRecord orderRebateRecord : orderRebateRecordList){
            orderRebateRecordMapper.insertSelective(orderRebateRecord);
        }
    }

    /**
     * 查询商品信息
     *
     * @param customerId
     * @param skuIds
     * @return
     * @author wangxiaoshun
     */
    public Map<Long, ProductShopcarSkuVO> querySkuInfos(Long customerId, List<Long> skuIds) {
        ProductSkuListCondition productCondition = new ProductSkuListCondition();
        productCondition.setSkuIdList(skuIds);
        productCondition.setCustomerId(customerId);
        ResponseResult<Map<Long, ProductShopcarSkuVO>> ret = productServiceClient.findShopcarSkuList(productCondition);
        if (null == ret.getData() || ret.getData().isEmpty()) {
            logger.error("商品：skuIds={}, 返回结果:code={} 商品库中不存在，创建订单异常！~",
                    Arrays.toString(skuIds.toArray()), ret == null ? null : ret.getCode());
            throw new BusinessException(BusinessCode.CODE_401005);
        }
        return ret.getData();
    }

    /**
     * 生成订单号  格式：C+YYMMDDHH(年月日小时8位)XXXXXXXXX(9位随机吗)= 18位
     *
     * @return
     * @author wangxiaoshun
     */
    private String generateOrderNo() {
        String orderNo = null;
        Date date = new Date();
        do {
            UUID uuid = UUID.randomUUID();
            int hashCodeV = (uuid.toString() + System.currentTimeMillis()).hashCode();
            if (hashCodeV < 0) {
                // 有可能是负数
                hashCodeV = -hashCodeV;
            }
            while (hashCodeV > MAX_ORDER_POSTFIX) {
                hashCodeV = hashCodeV >> 1;
            }
            String orderNoDateTimeFormatter = "yyMMddHH";
            // 0 代表前面补充0
            // 9 代表长度为4
            // d 代表参数为正数型
            String randomFormat = "%09d";
            orderNo = "Y" + DateFormatUtils.format(date, orderNoDateTimeFormatter) + String.format(randomFormat, hashCodeV);
        } while (!checkOrderNoAvailable(orderNo, date));
        return orderNo;
    }

    /**
     * 校验订单号生成是否重复
     *
     * @param orderNo
     * @param date
     * @return
     * @author wangxiaoshun
     */
    private boolean checkOrderNoAvailable(String orderNo, Date date) {

        String orderNoDateTimeFormatter = "yyMMddHH";
        String val = cache.hget(CacheName.CACHE_KEY_ORDERNO_CHECK_EXISTS + DateFormatUtils.format(date, orderNoDateTimeFormatter), orderNo);
        if (StringUtils.isNotBlank(val)) {
            logger.info("订单号生成出现重复：orderNo={}", orderNo);
            return false;
        } else {
            cache.hset(CacheName.CACHE_KEY_ORDERNO_CHECK_EXISTS + DateFormatUtils.format(date, orderNoDateTimeFormatter), orderNo, orderNo);
            //下一小时就过期
            Long expires = (DateUtils.truncate(DateUtils.addHours(date, 1), Calendar.HOUR_OF_DAY).getTime() - date.getTime()) / 1000;
            cache.expire(CacheName.CACHE_KEY_ORDERNO_CHECK_EXISTS + DateFormatUtils.format(date, orderNoDateTimeFormatter), expires.intValue());
            return true;
        }
    }

    /**
     * 订单下单条件校验
     *
     * @param orderCreateCondition
     * @author wangxiaoshun
     * @author wangxiaoshun
     */
    private void validateOrderCreateCondition(OrderCreateCondition orderCreateCondition) {
        if (orderCreateCondition.getDealerId() == null) {
            throw new BusinessException(BusinessCode.STORE_ID_EMPTY);
        }
        if (orderCreateCondition.getPayType() == null) {
            throw new BusinessException(BusinessCode.CODE_401003);
        }
        if (orderCreateCondition.getProductItemConditions() == null || orderCreateCondition.getProductItemConditions().isEmpty()) {
            throw new BusinessException(BusinessCode.CODE_401005);
        }

        ResponseResult<CustomerUserInfoVO> result = customerServiceClient.getCustomerUserInfoById(orderCreateCondition.getCustomerId());

        CustomerUserInfoVO customerUserInfoVO = result.getDataWithException();
        if(null== customerUserInfoVO){
            logger.info("订单创建用户信息为空，用户ID ：" + orderCreateCondition.getCustomerId());
            throw new BusinessException(BusinessCode.CODE_401009);
        }
        if(customerUserInfoVO.getStatus()==0){
            logger.info("订单创建用户未激活，用户ID ：{}，状态：{}" , orderCreateCondition.getCustomerId(),customerUserInfoVO.getStatus());
            throw new BusinessException(BusinessCode.CODE_401013);
        }

        for (Iterator<OrderProductItemCondition> iterator = orderCreateCondition.getProductItemConditions().iterator(); iterator.hasNext(); ) {
            OrderProductItemCondition condition = iterator.next();

            if(null != condition.getShopCarId()&& condition.getShopCarId().intValue() >0){
                OrderShoppingCart orderShoppingCart = shoppingCartMapper.selectByPrimaryKey(condition.getShopCarId());
                if(null==orderShoppingCart){
                    logger.info("订单创建购物车为空，购物车ID ：" + condition.getShopCarId());
                    throw new BusinessException(BusinessCode.CODE_401012);
                }
                if(orderShoppingCart.getStatus()!=OrderCartStatusEnum.EFFECTIVE.getStatusCode()){
                    logger.info("订单创建购物车无效，购物车ID ：{}，状态：{}" , condition.getShopCarId(),orderShoppingCart.getStatus());
                    throw new BusinessException(BusinessCode.CODE_401012);
                }
            }

            if (condition.getNumber() == null || condition.getNumber().intValue() < 1) {
                throw new BusinessException(BusinessCode.CODE_401006);
            }
            if (condition.getSkuId() == null) {
                throw new BusinessException(BusinessCode.CODE_401007);
            }
        }
    }


    /**
     * 订单取消service 超时订单和取消订单
     *
     * @param order        订单
     * @param cancelReason 取消原因
     * @param extendStatus
     * @param cancelType
     * @param cancelType
     * @author wangxiaoshun
     */
    @Override
    public void orderCancel(OrderInfo order, String cancelReason,Integer status, Integer extendStatus, Integer cancelType, String cancelCode,String operationProperty) {
        logger.info("取消订单-开始-订单号={},cancelReason={}", order.getOrderNo(), cancelReason);
        order.setStatus(status);
        order.setExtendStatus(extendStatus);
        order.setUpdated(new Date());
        order.setCloseTime(new Date());
        orderInfoMapper.updateByPrimaryKeySelective(order);

        //添加订单日志
        saveOrderLog(order, operationProperty);
        //保存订单取消原因
        saveOrderCancelInfo(order, cancelReason, cancelType, cancelCode);
        logger.info("取消订单-结束-订单号={}", order.getOrderNo());

        //收益改为已关闭
        OrderRebateRecord rebateRecord=new OrderRebateRecord();
        rebateRecord.setOrderNo(order.getOrderNo());
        rebateRecord.setStatus(OrderRebateStatusEnum.HAS_CLOSED.getStatusCode());
        orderRebateRecordMapper.updateStatusByOrderNo(rebateRecord);

        //订单取消操作库存
        List<OrderDetailVO>  orderDetailVOList = orderDetailMapper.selectListByOrderNo(order.getOrderNo());
        orderOperateProductStock(orderDetailVOList,order,2);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void orderComplete(OrderInfo orderInfo) {
        String log="订单自动闭环--订单号："+orderInfo.getOrderNo()+",";
        logger.info(log+"开始");
        String orderNo=orderInfo.getOrderNo();
        int extendStatus=orderInfo.getExtendStatus()==null?-1:orderInfo.getExtendStatus().intValue();
        int orderStatus=orderInfo.getStatus()==null?-1:orderInfo.getStatus().intValue();
        if ( OrderStatusEnum.CLOSE.getStatusCode() == orderStatus ){
            //如果订单状态是关闭状态
            logger.info(log+"订单状态为：{}，该订单状态为已关闭，不能继续操作。",orderInfo.getStatus());
            return;
        }
        if ( OrderStatusEnum.FINISHED.getStatusCode() == orderStatus ){
            //如果订单状态是已完成（闭环）状态
            logger.info(log+"订单状态为：{}，该订单状态为已完成，不能继续操作。",orderInfo.getStatus());
            return;
        }
        if ( OrderStatusEnum.CANCELED.getStatusCode() == orderStatus ){
            //如果订单状态是已取消状态
            logger.info(log+"订单状态为：{}，该订单状态为已取消，不能继续操作。",orderInfo.getStatus());
            return;
        }
        //获取订单当前可以操作状态，1 有未完成的售后 （有可能自动确认收货订单）2 关闭订单 3 闭环订单
        int status=orderAfterSaleDetailService.getOrderStatus(orderNo);

        if (status == OrderAfterSaleDetailServiceImpl.TEMP_ORDER_STATUS_NORMAL){
            if (OrderExtendStatusEnum.MANUAL_CONFIRM.getStatusCode() == extendStatus){
                //有未完成的售后，并且已经手动收货，不做任何操作
                logger.info(log+"已经手动确认收货，无需自动确认收货");
                return;
            }else{
                logger.info(log+"自动确认收货");
                //有未完成的售后，并且没有手动收货，订单状态变成已收货，订单扩展状态变成自动收货
                orderInfo.setStatus(OrderStatusEnum.RECEIVIED.getStatusCode());
                orderInfo.setReceiveTime(new Date());
                orderInfo.setExtendStatus(OrderExtendStatusEnum.AUTO_CONFIRM.getStatusCode());
                orderInfo.setUpdatedBy(UpdatedByEnum.AUTOMATIC.getTypeCode());
                orderInfo.setUpdated(new Date());
                orderInfoMapper.updateByPrimaryKeySelective(orderInfo);

                // 生成订单日志
                saveOrderLog(orderInfo, OrderOperationPropertyEnum.AUTO_RECEIVE.getPropertyDes());
            }
        }else if ( status == OrderAfterSaleDetailServiceImpl.TEMP_ORDER_STATUS_CLOSE ){
            logger.info(log+"关闭订单");
            //订单所有商品都退货，状态变成已关闭，没有扩展状态
            orderInfo.setStatus(OrderStatusEnum.CLOSE.getStatusCode());
            orderInfo.setCloseTime(new Date());
            orderInfo.setUpdatedBy(UpdatedByEnum.AUTOMATIC.getTypeCode());
            orderInfo.setUpdated(new Date());
            orderInfoMapper.updateByPrimaryKeySelective(orderInfo);
            //修改收益状态
            orderAfterSaleDetailService.updateRebateRecord(orderNo);
            // 生成订单日志
            saveOrderLog(orderInfo, OrderOperationPropertyEnum.CLOSE_ORDER.getPropertyDes());

        }else if ( status == OrderAfterSaleDetailServiceImpl.TEMP_ORDER_STATUS_FINISHED ){
            logger.info(log+"闭环订单");
            if (OrderStatusEnum.RECEIVIED.getStatusCode() != orderStatus &&
                    OrderStatusEnum.WAIT_RECEIVING.getStatusCode() != orderStatus ){
                //如果订单状态不是已收货 或者待收货  不能闭环
                logger.info(log+"订单状态为：{}，该状态不能闭环订单。",orderInfo.getStatus());
                return;
            }
            //订单还有正常交易商品，状态变成已完成
            orderInfo.setCompleteTime(new Date());
            orderInfo.setStatus(OrderStatusEnum.FINISHED.getStatusCode());
            //如果没有手动收货，扩展状态变成自动收货
            if (OrderExtendStatusEnum.MANUAL_CONFIRM.getStatusCode() != extendStatus){
                orderInfo.setExtendStatus(OrderExtendStatusEnum.AUTO_CONFIRM.getStatusCode());
            }
            orderInfo.setUpdatedBy(UpdatedByEnum.AUTOMATIC.getTypeCode());
            orderInfo.setUpdated(new Date());
            orderInfoMapper.updateByPrimaryKeySelective(orderInfo);
            //修改收益状态
            orderAfterSaleDetailService.updateRebateRecord(orderNo);
            // 生成订单日志
            saveOrderLog(orderInfo, OrderOperationPropertyEnum.FINISH_ORDER.getPropertyDes());
            //发送订单闭环事件
            orderFinishSendEvent(orderNo);
        }
    }

    /**
     * 发送订单闭环事件
     * @param orderNo
     */
    @Override
    public  void  orderFinishSendEvent(String orderNo){
        logger.info("订单发送闭环事件开始-订单号={}", orderNo);
        List<OrderRebateRecord> rebateList = orderRebateRecordMapper.selectByPrimaryKey(orderNo);
        OrderRebateRecordVO orderRebateRecordVO = new OrderRebateRecordVO();
        orderRebateRecordVO.setOrderNo(orderNo);
        orderRebateRecordVO.setOrderRebateRecordList(rebateList);
        eventMessageSender.send(EventType.OUTLET_EVENT_CUSTOMER_ORDER_FINISHED, orderNo, orderRebateRecordVO);
        logger.info("订单发送闭环事件结束-订单号={}", orderNo);
    }



    @Override
    public List<OrderRebateRecord> getOrderRebateRecordVO(String orderNo) {
        return orderRebateRecordMapper.selectByPrimaryKey(orderNo);
    }

    @Override
    public OrderInfo modifyOrderRebateRecord(OrderRebateRecordCondition condition) {
        OrderInfo orderInfo = orderInfoMapper.selectByOrderNo(condition.getOrderNo());
        if (orderInfo == null) {
            logger.info("订单号：{}未找到对应订单，无法执行修改订单实际收益", condition.getOrderNo());
            return orderInfo;
        }

        orderInfo.setActualProfit(condition.getProfit());
        orderInfo.setActualIntegral(Long.valueOf(condition.getIntegral()==null?0:condition.getIntegral()));
        orderInfoMapper.updateByOrderNo(orderInfo);
        logger.info("订单号：{} ,修改收益信息表实际收益开始", condition.getOrderNo());
        for(OrderRebateRecordUpdateCondition orderRebateRecordUpdateCondition : condition.getOrderRebateRecordUpdateConditions()){
            OrderRebateRecord orderRebateRecord = orderRebateRecordMapper.selectRebateByOrderNoAndSkuId(orderRebateRecordUpdateCondition.getOrderNo(),orderRebateRecordUpdateCondition.getSkuId());
            orderRebateRecord.setFirstAgentActualProfit(orderRebateRecordUpdateCondition.getFirstProfit());
            orderRebateRecord.setFirstAgentActualIntegral(orderRebateRecordUpdateCondition.getFirstIntegral());

            orderRebateRecord.setTwoAgentActualProfit(orderRebateRecordUpdateCondition.getTwoProfit());
            orderRebateRecord.setTwoAgentActualIntegral(orderRebateRecordUpdateCondition.getTwoIntegral());

            orderRebateRecord.setVipActualProfit(orderRebateRecordUpdateCondition.getMemberProfit());
            orderRebateRecord.setVipActualIntegral(orderRebateRecordUpdateCondition.getMemberIntegral());
            orderRebateRecord.setStatus(OrderRebateStatusEnum.HAH_CORRECTION.getStatusCode());
            orderRebateRecordMapper.updateByPrimaryKey(orderRebateRecord);
        }
        logger.info("订单号：{} ,修改收益信息表实际收益结束", condition.getOrderNo());

        return orderInfo;
    }

    @Override
    public OrderInfoVO selectInfoByOrderNo(String orderNo) {
        OrderAfterSaleCondition orderAfterSaleCondition = new OrderAfterSaleCondition();
        orderAfterSaleCondition.setOrderNo(orderNo);
        return orderInfoMapper.selectOrderInfoByCondition(orderAfterSaleCondition);
    }

    /**
     * 保存订单取消原因
     *
     * @param orderInfo
     * @param cancelReason
     * @param cancelType
     * @param cancelCode
     * @author wangxiaoshun
     */
    private void saveOrderCancelInfo(OrderInfo orderInfo, String cancelReason, Integer cancelType, String cancelCode) {
        OrderCancelInfo orderCancelInfo = new OrderCancelInfo();
        orderCancelInfo.setOrderNo(orderInfo.getOrderNo());
        orderCancelInfo.setOrderDictCode(cancelCode);
        orderCancelInfo.setOrderDictType(cancelType);
        orderCancelInfo.setRemarks(cancelReason);
        orderCancelInfoMapper.insertSelective(orderCancelInfo);
    }

    /**
     * 保存订单日志
     *
     * @param orderInfo
     * @param operationProperty
     * @author wangxiaoshun
     */
    private void saveOrderLog(OrderInfo orderInfo, String operationProperty) {
        // 生成订单日志
        OrderLog orderLog = new OrderLog();
        orderLog.setOperationProperty(operationProperty);
        orderLog.setCreated(new Date());
        orderLog.setOrderNo(orderInfo.getOrderNo());
        orderLogMapper.insertSelective(orderLog);
    }

    /**
     * 订单购物车转换关系
     * @param orderInfoVO
     * @param orderCreateCondition
     */
    private void saveOrderShoppingLink(OrderInfoVO orderInfoVO,OrderCreateCondition orderCreateCondition) {
        for(OrderProductItemCondition orderProductItemCondition : orderCreateCondition.getProductItemConditions()){
            if(null == orderProductItemCondition.getShopCarId()){
                continue;
            }
            OrderShoppingLink shoppingLink = new OrderShoppingLink();
            shoppingLink.setCreated(orderInfoVO.getCreated());
            shoppingLink.setOrderNo(orderInfoVO.getOrderNo());
            shoppingLink.setShopCarId(orderProductItemCondition.getShopCarId());
            orderShoppingLinkMapper.insertSelective(shoppingLink);

            //更新购物车状态
            OrderShoppingCart orderShoppingCart = new OrderShoppingCart();
            orderShoppingCart.setId(orderProductItemCondition.getShopCarId());
            orderShoppingCart.setStatus(OrderCartStatusEnum.TRANSFER_ORDER.getStatusCode());
            shoppingCartMapper.updateByPrimaryKeySelective(orderShoppingCart);
        }
    }

    /**
     * @author wangxiaoshun
     * 订单作库存
     * @param orderDetailVOList
     * @param type 1 代表减库存传正数 2 代表加库存传负数
     */
    private void orderOperateProductStock(List<OrderDetailVO> orderDetailVOList,OrderInfo orderInfo,Integer type) {
        List<ProductStockSkuCondition> condition = new ArrayList<>();
        //组装入参
        for(OrderDetailVO orderDetailVO :orderDetailVOList){
            ProductStockSkuCondition productStockSkuCondition = new ProductStockSkuCondition();
            productStockSkuCondition.setSkuId(orderDetailVO.getSkuId());
            if(type == 1){
                productStockSkuCondition.setSkuNum(Long.valueOf(orderDetailVO.getNumber()==null ? 0:orderDetailVO.getNumber()));
            }else{
                productStockSkuCondition.setSkuNum(Long.valueOf(orderDetailVO.getNumber()==null ? 0:orderDetailVO.getNumber())*-1);
            }
            condition.add(productStockSkuCondition);
        }

        logger.info("订单号：{} ,订单修改库存,condition:{}", orderInfo.getOrderNo(),Arrays.toString(condition.toArray()));
        productServiceClient.operateSubProductStock(condition).getDataWithException();
        logger.info("订单号：{} ,订单修改库存 结束,condition:{} ", orderInfo.getOrderNo(),Arrays.toString(condition.toArray()));
    }

    /**
     * @author hjw
     * @date 2019/1/16 10:27
     * @param orderBaseConditions
     * @Description  手动确认收货
     * @return
     */
    @Override
    public void manualReceived(OrderBaseConditions orderBaseConditions){
        String orderNo = orderBaseConditions.getOrderNo();
        //校验订单是否自动确认收货
        OrderInfo oInfo = this.selectByOrderNo(orderNo);
        if(oInfo.getStatus() != OrderStatusEnum.WAIT_RECEIVING.getStatusCode()){
            logger.error("=--更新订单{}状态失败,当前订单状态是{}",orderNo,oInfo.getStatus());
            throw  new BusinessException(BusinessCode.ORDER_STATUS_CHANGE_FAILURE);
        }
        int i = oInfo.getAutoReceiveDay().intValue() * 24 * 60;
        if(OrderUtils.isAutoRecive(oInfo.getSendTime(),i)){
            logger.error("订单{}已自动确认收货，不能再进行任何操作！！",orderNo);
            throw new BusinessException(BusinessCode.CODE_440601);
        }
        //校验是否有未审核的售后订单
        List<OrderAfterSaleDetail> afterSaleList = orderAfterSaleDetailMapper.selectListByOrderNo(orderNo);
        List<OrderAfterSaleDetail> afterSaleListWait = new ArrayList<>();
        for(int j=0;j<afterSaleList.size();j++){
            //如果有售后，则不能确认收货
            OrderAfterSaleDetail orderAfterSaleDetail = afterSaleList.get(j);
            if(orderAfterSaleDetail.getAfterSaleStatus().equals(AfterSaleAuditStatusEnum.YES.getTypeCode()) && orderAfterSaleDetail.getCompleteStatus().equals(AfterSaleCompleteStatusEnum.UNCOMPLETED.getTypeCode())){
                logger.error("订单{}有正在售后中的商品{},不能确认收货！！",orderNo,orderAfterSaleDetail.getSkuId());
                throw new BusinessException(BusinessCode.CODE_405805);
            }
            //是否有未审核的订单
            if(orderAfterSaleDetail.getAfterSaleStatus().equals(AfterSaleAuditStatusEnum.PROCESSING.getTypeCode())){
                afterSaleListWait.add(orderAfterSaleDetail);
            }
        }
        //订单主状态变为【待收货】从状态为【已收货】 自动收货和订单完成放在发货时候发起的延时队列中完成
        OrderInfo oInfoN = new OrderInfo();
        oInfoN.setOrderNo(orderNo);
        oInfoN.setStatus(OrderStatusEnum.RECEIVIED.getStatusCode());
        oInfoN.setUpdated(new Date());
        oInfoN.setUpdatedBy(String.valueOf(orderBaseConditions.getCustomerId()));
        //此时不代表订单变成真正的闭环，所以不更新收益和积分
        int uCount = this.updateByOrderNo(oInfoN);
        if(uCount != 1){
            logger.error("=--更新订单{}状态失败",orderNo);
            throw  new BusinessException(BusinessCode.ORDER_STATUS_CHANGE_FAILURE);
        }
        OrderLog log = new OrderLog();
        log.setOrderNo(orderNo);
        log.setCreated(new Date());
        log.setOperationProperty(OrderOperationPropertyEnum.RECEIVE.getPropertyDes());
        orderLogMapper.insert(log);
        //如果有未审核的订单，修改售后订单状态
        afterSaleListWait.forEach(as -> {
            OrderAfterSaleDetail afterSaleDetail = new OrderAfterSaleDetail();
            afterSaleDetail.setId(as.getId());
            afterSaleDetail.setResultStatus(AfterSaleAuditStatusEnum.CANCEL.getTypeCode());
            afterSaleDetail.setCompleteStatus(CommonStatusEnum.YES.getTypeCode());
            afterSaleDetail.setViewStatus(AfterSaleViewStatusEnum.CANCLED.getTypeCode());
            Date now = new Date();
            afterSaleDetail.setCancelTime(now);
            afterSaleDetail.setCompleteTime(now);
            afterSaleDetail.setUpdated(now);
            afterSaleDetail.setUpdatedBy(String.valueOf(orderBaseConditions.getCustomerId()));
            afterSaleDetailService.cancelOrderAfterSaleApply(afterSaleDetail);
        });

    }

    /**
     * @author hjw
     * @date 2019/1/16 10:27
     * @param orderBaseConditions
     * @Description  手动确认收货
     * @return
     */
    @Override
    public void manualReceivedv2(OrderBaseConditions orderBaseConditions){
        String orderNo = orderBaseConditions.getOrderNo();
        //校验订单是否自动确认收货
        OrderInfo oInfo = this.selectByOrderNo(orderNo);
        if(oInfo.getStatus() != OrderStatusEnum.WAIT_RECEIVING.getStatusCode()){
            logger.error("=--更新订单{}状态失败,当前订单状态是{}",orderNo,oInfo.getStatus());
            throw  new BusinessException(BusinessCode.ORDER_STATUS_CHANGE_FAILURE);
        }
        int i = oInfo.getAutoReceiveDay().intValue() * 24 * 60;
        if(OrderUtils.isAutoRecive(oInfo.getSendTime(),i)){
            logger.error("订单{}已自动确认收货，不能再进行任何操作！！",orderNo);
            throw new BusinessException(BusinessCode.CODE_440601);
        }
        //订单主状态变为【待收货】从状态为【已收货】 自动收货和订单完成放在发货时候发起的延时队列中完成
        OrderInfo oInfoN = new OrderInfo();
        oInfoN.setOrderNo(orderNo);
        oInfoN.setStatus(OrderStatusEnum.RECEIVIED.getStatusCode());
        oInfoN.setExtendStatus(OrderExtendStatusEnum.MANUAL_CONFIRM.getStatusCode());
        oInfoN.setUpdated(new Date());
        oInfoN.setUpdatedBy(String.valueOf(orderBaseConditions.getCustomerId()));
        //此时不代表订单变成真正的闭环，所以不更新收益和积分
        int uCount = this.updateByOrderNo(oInfoN);
        if(uCount != 1){
            logger.error("=--更新订单{}状态失败",orderNo);
            throw  new BusinessException(BusinessCode.ORDER_STATUS_CHANGE_FAILURE);
        }
        OrderLog log = new OrderLog();
        log.setOrderNo(orderNo);
        log.setCreated(new Date());
        log.setOperationProperty(OrderOperationPropertyEnum.RECEIVE.getPropertyDes());
        orderLogMapper.insert(log);
    }
}
